package com.lihaozhe.orderservice.util;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * Loadbalancer工具
 *
 * @author 李昊哲
 * @version 1.0.0
 */
@Component
public class LoadbalancerUtil {
  private final DiscoveryClient discoveryClient;
  private final LoadBalancerClient loadBalancerClient;
  @Qualifier("loadBalancedRestClient")
  private final RestClient loadBalancedRestClient;

  /**
   * 构造函数，注入依赖
   */
  public LoadbalancerUtil(DiscoveryClient discoveryClient,
                          LoadBalancerClient loadBalancerClient, RestClient loadBalancedRestClient) {
    this.discoveryClient = discoveryClient;
    this.loadBalancerClient = loadBalancerClient;
    this.loadBalancedRestClient = loadBalancedRestClient;
  }

  /**
   * 获取当前服务实例信息
   *
   * @return 当前服务实例列表
   */
  public List<ServiceInstance> getDiscoveryClient(String serviceId) {
    return discoveryClient.getInstances(serviceId);
  }


  /**
   * 获取当前选择的服务实例
   *
   * @return 当前选择的服务实例
   */
  public ServiceInstance getCurrentServiceInstance(String serviceId) {
    return loadBalancerClient.choose(serviceId);
  }

  /**
   * 随机获取某服务实例主机
   *
   * @param serviceId 服务实例
   * @return 服务实例主机 URI 地址
   */
  public String randomServiceUrl(String serviceId) {
    List<ServiceInstance> instances = getDiscoveryClient(serviceId);
    ServiceInstance instance = instances.get(ThreadLocalRandom.current().nextInt(instances.size()));
    return instance.getUri().toString();
  }

  /**
   * 获取某服务实例主机
   *
   * @param serviceId 服务实例
   * @return 服务实例主机 URI 地址
   */
  public String getCurrentServiceUrl(String serviceId) {
    return getCurrentServiceInstance(serviceId).getUri().toString();
  }

  public LoadBalancerClient getLoadBalancerClient() {
    return loadBalancerClient;
  }

  public RestClient getLoadBalancedRestClient() {
    return loadBalancedRestClient;
  }
}
